package ldh.im.fxgui.component;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import ldh.im.fxbase.util.MovableHelper;
import ldh.im.fxbase.util.RegionUtil;
import ldh.im.fxbase.util.ResizeHelper;
import ldh.im.fxgui.controller.StageControlController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ImStage extends Stage {

    private static final Logger LOGGER = LoggerFactory.getLogger(ImStage.class);

    private StackPane root;
    private VBox contentPane;
    private Label titleLabel;
    private Pane movablePane;
    private HBox headerPane;
    private StageControlController stagePaneController;

    private ObjectProperty<ImageView> stageIconProperty = new SimpleObjectProperty<>();
    private ObjectProperty<Node> contentProperty = new SimpleObjectProperty<>();

    private Scene scene;
    private double width = -1;
    private double height = -1;

    public ImStage(double width, double height) {
        this.width = width;
        this.height = height;
        loadFxml();
    }

    public ImStage() {
        loadFxml();
    }

    public Scene getCurrentScene() {
        return scene;
    }

    public ImageView getStageIconProperty() {
        return stageIconProperty.get();
    }

    public ObjectProperty<ImageView> stageIconPropertyProperty() {
        return stageIconProperty;
    }

    public void setStageIconProperty(ImageView stageIconProperty) {
        this.stageIconProperty.set(stageIconProperty);
    }

    public Node getContentProperty() {
        return contentProperty.get();
    }

    public ObjectProperty<Node> contentPropertyProperty() {
        return contentProperty;
    }

    public void setContent(Node contentPane) {
        this.contentProperty.set(contentPane);
    }

    public StackPane getRoot() {
        return this.root;
    }

    private void initStage() {
        this.initStyle(StageStyle.TRANSPARENT);

        if (width > 0 && height > 0) {
            scene = new Scene(root, width, height);
        } else {
            scene = new Scene(root);
        }
        LOGGER.debug("newStage scene {}, stage: {}", scene, this);

        scene.setFill(null);
        scene.getStylesheets().add(this.getClass().getResource("/css/var.css").toExternalForm());
        scene.getStylesheets().add(this.getClass().getResource("/css/stage.css").toExternalForm());
        scene.getStylesheets().add(this.getClass().getResource("/css/scrollbar.css").toExternalForm());
        scene.getStylesheets().add(this.getClass().getResource("/css/bootstrapfx.css").toExternalForm());
        this.setScene(scene);
        MovableHelper.movable(movablePane);

        stagePaneController.setStage(this);

        ResizeHelper.addResizeListener(this);
    }

    private void bindEvent() {
        stageIconProperty.addListener((InvalidationListener)->{
            if (stageIconProperty.get() != null) {
                if (headerPane.getChildren().size() > 3) {
                    headerPane.getChildren().remove(0);
                }
                headerPane.getChildren().add(0, stageIconProperty.get());
            }
        });

        contentProperty.addListener(l->{
            if (contentProperty.get() != null) {
                if (contentPane.getChildren().size() > 1) {
                    contentPane.getChildren().remove(1);
                }
                VBox.setVgrow(contentProperty.get(), Priority.ALWAYS);
                contentPane.getChildren().add(contentProperty.get());
            }
        });

        titleLabel.textProperty().bind(titleProperty());
    }

    private void loadFxml() {
        buildUi();

        initStage();
        bindEvent();
    }

    private void buildUi() {
        root = new StackPane();

        contentPane = new VBox();
        contentPane.getStyleClass().add("stage-pane");

        headerPane = new HBox();
        headerPane.getStyleClass().add("header-pane");

        titleLabel = new Label();
        titleLabel.getStyleClass().add("title-label");

        movablePane = new Pane();

        RegionUtil.FxmlBean<HBox, StageControlController> fxmlBean = RegionUtil.loadFxmlBean(getClass().getResource("/fxml/StageControlPane.fxml"));
        this.stagePaneController = fxmlBean.getController();

        headerPane.getChildren().addAll(titleLabel, movablePane, fxmlBean.getNode());
        HBox.setHgrow(movablePane, Priority.ALWAYS);

        contentPane.getChildren().add(headerPane);
        root.getChildren().add(contentPane);
    }
}
